package study.javabasic.mymap;


/**
 *
 * @author zhangshuhan
 * @date 2019/3/25
 */
public class MyMap<K, V> {

    /**
     * 负载因子
     */
    public float loadFactor = 0.75f;
    /**
     * 初始化的值
     */
    public int size = 0;
    /**
     * hash桶
     */
    public MyEntry<K, V>[] table;


    public int defaultSize = 16;

    public MyMap() {
        this.table = new MyEntry[defaultSize];
    }

    public void put(K key, V value) {
        //根据key计算hash桶具体位置
        //判断是否需要扩容
        if (size>=table.length*loadFactor){
            upSize();
        }
        int index = myHash(key, table.length);
        //构建一个entry
        MyEntry myEntry = new MyEntry(key, value, null);
        //判断当前的桶是否为空
        if (table[index] == null) {
            table[index] = myEntry;
        } else {
            //当前桶不为空通过尾插法进行插入
            MyEntry tem = table[index];
            if (tem.getKey().equals(key)) {
                tem.setValue(value);
                return;
            }
            while (tem.next != null) {
                //判断key是否重复
                tem = tem.next;
                if (key.equals(tem.getKey())) {
                    tem.setValue(value);
                    return;
                }
            }
            tem.next = myEntry;
        }
        size++;
    }


    private Object get(Object key) {

        int index = myHash(key, table.length);
        //计算出hash后 对当前桶进行遍历
        MyEntry temEntry = table[index];
        if (null == temEntry) {
            return null;
        }
        while (temEntry != null) {
            if (temEntry.getKey().equals(key)) {
                return temEntry.getValue();
            }
            temEntry = temEntry.next;
        }
        return null;

    }
    /**
     *
     */
    private void upSize() {
        MyEntry[] newTable = new MyEntry[table.length * 2];
        //遍历原来的table
        for (int i = 0; i < table.length; i++) {
            MyEntry<K,V> myEntry = table[i];
            while (null != myEntry) {
                putByNewTable(myEntry.getKey(), myEntry.getValue(), newTable);
                myEntry = myEntry.next;
            }
        }
        table = newTable;
    }

    private void putByNewTable(K k, V v, MyEntry<K, V>[] newTable) {
        int index = myHash(k, newTable.length);
        MyEntry entry = new MyEntry(k, v, null);
        if (newTable[index] == null) {
            //构建一个entry  放进去
            newTable[index] = entry;
        } else {
            //不是null
            MyEntry tem = newTable[index];
            if (tem.getKey().equals(k)) {
                tem.setValue(v);
                return;
            }
            while (tem.next != null) {
                tem = tem.next;
                if (k.equals(tem.getKey())) {
                    tem.setValue(v);
                    return;
                }
            }
            tem.next = entry;
        }
    }


    private int myHash(Object key, int length) {
        return key.hashCode()%(length);
    }

    public static void main(String[] args) {
        MyMap<Integer, Integer> myMap = new MyMap();
        for (int i = 0; i < 100; i++) {
            myMap.put(i,i);
        }
        System.out.println(String.valueOf(myMap.get(99)));
    }
}
